///@file ResultTable.cpp
///@brief Implementation of the class representing a table of results
///@author Arnaud Duval
///@version 0.0
///@date 2010/05/26


#include "ResultTable.h"

///@brief Default constructor
ResultTable::ResultTable()
{
	nbLines = 0u;
	nbColumns = 0u;
}

///@brief Constructor form a text file
///@param file name of the file to read
///@param lines number of lines to read
///@param cols number of columns to read
///@param titlePresent set to true if the labels are present in the text file
///@warning The feature to read labels from the input text file is not implemented
ResultTable::ResultTable(std::string file, unsigned int lines, unsigned int cols, bool titlePresent)
{
	std::ifstream f(file.c_str());
	nbLines = lines;
	nbColumns = cols;
	data = new double*[nbColumns];
	for(unsigned int i = 0 ; i < nbColumns ; i++)
		data[i] = new double[nbLines];
	for(unsigned int i = 0 ; i < nbLines ; i++)
		for(unsigned int j = 0 ; j < nbColumns ; j++)
			f >> data[j][i];
	f.close();
}

///@brief Destructor
ResultTable::~ResultTable()
{
	for(unsigned int i = 0 ; i < nbColumns ; i++)
		delete[] data[i];
	delete[] data;
}

///@brief Write part of result in an output file
///@param outfile Name of the output file
///@param nbColsOut Number of columns in the output file
///@param indexes indexes of the columns to be written
void ResultTable::WriteResult(std::string outfile, unsigned int nbColsOut, unsigned int* indexes)
{
	std::ofstream f(outfile.c_str());
	for(unsigned int i = 0 ; i < nbLines ; i++)
	{
		for(unsigned int j = 0 ; j < nbColsOut ; j++)
		{
			f << data[indexes[j]-1][i] << "\t";
		}
		f << "\n";
	}
	f.close();
}

///@brief Write a normalized file
///@param outfile Name of the outfile (without extension)
void ResultTable::WriteFile(std::string outfile)
{
	std::string ext = ".rTable";
	outfile += ext;
	std::ofstream f(outfile.c_str());
	f << "[Nb de colonnes]\n";
	f << nbColumns << "\n";
	f << "[Nb de lignes]\n";
	f << nbLines << "\n";
	f << "[Titres des colonnes]\n";
	for(unsigned int i = 0 ; i < nbColumns ; i++)
		f << titles[i].c_str() << "\n";
	f << "[Donnees]\n";
	for(unsigned int i = 0 ; i < nbLines ; i++)
	{
		for(unsigned int j = 0 ; j < nbColumns ; j++)
		{
			f << data[j][i];
			if(j != nbColumns-1)
				f << "\t";
		}
		if (i != nbLines-1)
			f << "\n";
	}
	f.close();
}

/*///@brief Read a normalized file
///@param infile Name of the inputfile (without extension)
void ResultTable::ReadFile(std::string infile)
{
	///NOTE : Il reste des trucs à coder ici
	std::string ext = ".rTable";
	infile = infile+ext;
	std::ifstream f(infile.c_str());
	//Lire l'information [Nb de colonnes]
	f >> nbColumns;
	//Lire l'information [Nb de lignes]
	f >> nbLines;
	//Créer la table et la liste de titres de colonnes
	//Lire l'information [Titres des colonnes]
	for(unsigned int i = 0 ; i < nbColumns ; i++)
		f >> titles[i] < "\n";
	//Lire l'information [Données]
	for(unsigned int i = 0 ; i < nbLines ; i++)
		for(unsigned int j = 0 ; j < nbColumns ; j++)
			f >> data[j][i];
	f.close();
	


}*/

//^^^^ WORK IN PROGRESS

///@brief Return the line where a maximum value is obtained
///@param n Index of column where the maximum value should be searched
double* ResultTable::GetMaxLine(unsigned int n)
{
	double *res = new double[nbColumns];
	double max = data[n-1][0];
	unsigned int maxindex = 0;
	for(unsigned int i = 0 ; i < nbLines ; i++)
	{
		if(data[n-1][i] > max)
		{
			max = data[n-1][i];
			maxindex = i;
		}
	}
	for(unsigned int j = 0 ; j < nbColumns ; j++)
	{
		res[j] = data[j][maxindex];
	}
	return res;
}

///@brief Return the line where a minimum value is obtained
///@param n Index of column where the minimum value should be searched
double* ResultTable::GetMinLine(unsigned int n)
{
	double *res = new double[nbColumns];
	double min = data[n-1][0];
	unsigned int minindex = 0;
	for(unsigned int i = 0 ; i < nbLines ; i++)
	{
		if(data[n-1][i] < min)
		{
			min = data[n-1][i];
			minindex = i;
		}
	}
	for(unsigned int j = 0 ; j < nbColumns ; j++)
	{
		res[j] = data[j][minindex];
	}
	return res;
}

///@brief Return average value of a columns
///@param n Index of the column for which the average value should be computed
double ResultTable::GetAverage(unsigned int n)
{
	double res = 0.;
	for(unsigned int i = 0 ; i < nbLines ; i++)
	{
		res+=data[n-1][i];
	}
	return res/nbLines;
}

///@brief Return Successives peaks
///@param n index of column for which the maximum value should be searched
///@param count Number of peaks, returned variable
double** ResultTable::GetMaxLines(unsigned int n, unsigned int& count)
{
	double **res;
	count = 0;
	for(unsigned int i = 1 ; i < nbLines-1 ; i++)
	{
		if((data[n-1][i] > data[n-1][i-1])&&(data[n-1][i] > data[n-1][i+1]))
		{
			count++;
		}
	}
	res = new double*[nbColumns];
	for(unsigned int i = 0 ; i < nbColumns ; i++)
		res[i] = new double[count];
	count = 0;
	for(unsigned int i = 1 ; i < nbLines-1 ; i++)
	{
		if((data[n-1][i] > data[n-1][i-1])&&(data[n-1][i] > data[n-1][i+1]))
		{
			for(unsigned int j = 0 ; j < nbColumns ; j++)
				res[j][count] = data[j][i];
			count++;
		}
	}
	return res;
}
